package com.kiki.song.controller;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

import com.alibaba.fastjson2.JSON;
import com.kiki.album.domain.Album;
import com.kiki.searchlog.domain.SearchLogDTO;
import com.kiki.singer.domain.Singer;
import com.kiki.song.domain.main.*;
import com.kiki.song.domain.recommend.ActionType;
import com.kiki.song.domain.recommend.UserActionEvent;
import com.kiki.song.domain.recommend.UserActionEventVo;
import com.kiki.song_category.domain.SongCategory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.kiki.common.annotation.Log;
import com.kiki.common.core.controller.BaseController;
import com.kiki.common.core.domain.AjaxResult;
import com.kiki.common.enums.BusinessType;
import com.kiki.song.service.ISongService;
import com.kiki.common.core.page.TableDataInfo;

/**
 * 音乐信息Controller
 * 
 * @author 林志毅
 * @date 2025-01-08
 */
@RestController
@RequestMapping("/song/song")
public class SongController extends BaseController
{
    @Autowired
    private ISongService songService;

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 查询音乐信息列表
     */
    @PreAuthorize("@ss.hasPermi('song:song:list')")
    @GetMapping("/list")
    public List<SongVo> list(Song song)
    {
        return songService.selectSongList(song);
    }

    /**
     *  获取最新音乐信息
     * @return
     */
    @GetMapping("/getNewSongs")
    public List<SongDTO> getNewSongs()
    {
        return songService.getNewSongs();
    }

    @GetMapping("/getEachTypeSongListCount")
    public List<TypeSongListCount> getEachTypeSongListCount()
    {
        return songService.getEachTypeSongListCount();
    }


    /**
     * 获取音乐信息详细信息
     */
    @PreAuthorize("@ss.hasPermi('song:song:query')")
    @GetMapping(value = "/{songId}")
    public AjaxResult getInfo(@PathVariable("songId") Long songId)
    {
        return success(songService.selectSongBySongId(songId));
    }

    /**
     * 新增音乐信息
     */
    @PreAuthorize("@ss.hasPermi('song:song:add')")
    @Log(title = "音乐信息", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody SongVo song)
    {
        return toAjax(songService.insertSong(song));
    }

    /**
     * 修改音乐信息
     */
    @PreAuthorize("@ss.hasPermi('song:song:edit')")
    @Log(title = "音乐信息", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody SongVo song)
    {
        return toAjax(songService.updateSong(song));
    }

    /**
     * 删除音乐信息
     */
    @PreAuthorize("@ss.hasPermi('song:song:remove')")
    @Log(title = "音乐信息", businessType = BusinessType.DELETE)
	@DeleteMapping("/{songIds}")
    public AjaxResult remove(@PathVariable Long[] songIds)
    {
        return toAjax(songService.deleteSongBySongIds(songIds));
    }
    /**
     * 查询热门音乐信息列表
     * @return
     */
    @GetMapping("/getHotSongList")
    public List<SongDTO> getHotSongList() {
        return songService.getHotSongList();
    }


    /**
     * 查询用户收藏音乐信息列表
     */
    @GetMapping("/listFavoriteByUserId/{userId}")
    public TableDataInfo listFavoriteByUserId(@PathVariable("userId") Long userId)
    {
        startPage();
        List<SongVo> list = songService.listFavoriteByUserId(userId);
        return getDataTable(list);
    }

    /**
     * 查询用户播放的历史音乐
     */
    @GetMapping("/listHistoryByUserId/{userId}")
    public TableDataInfo listHistoryByUserId(@PathVariable("userId") Long userId)
    {
        startPage();
        List<SongVo> list = songService.listHistoryByUserId(userId);
        return getDataTable(list);
    }

    /**
     * 根据歌手id查询音乐信息
     * @param singerId
     * @return
     */
    @GetMapping("/getSongListBySingerId/{singerId}")
    public List<SongVo> getSongListBySingerId(@PathVariable("singerId") Long singerId) {
        return songService.getSongListBySingerId(singerId);
    }


    /**
     * 根据专辑id查询音乐信息
     * @param albumId
     * @return
     */
    @GetMapping("/listByAlbumId/{albumId}")
    public List<SongVo> listByAlbumId(@PathVariable("albumId") Long albumId) {
//        System.out.println("接收"+albumId);
        return songService.selectSongListByAlbumId(albumId);
    }

    /**
     *  搜索音乐
     * @param
     * @return List<SongVo>
     */
    @PostMapping("/searchSong")
    public List<SongVo> searchSong(@RequestBody SearchLogDTO searchLogDTO) {
        // 打印接收的搜索日志DTO
        System.out.println("接收: " + searchLogDTO);

        // 获取关键词
        String keyword = searchLogDTO.getKeyword();
        if (keyword == null || keyword.isEmpty()) {
            throw new IllegalArgumentException("关键词不能为空");
        }

        // 获取用户ID（假设 SearchLogDTO 中包含 userId）
        Long userId = searchLogDTO.getUserId();
        if (userId == null) {
            throw new IllegalArgumentException("用户ID不能为空");
        }
        String userPrefix = "user:"; // 必须要有，不然没有目录效果
        String userPrefix2 = searchLogDTO.getUserId() + ":";
        String userPrefix3 = "search";
        String redisKey = userPrefix+userPrefix2+userPrefix3; // 使用用户ID作为队列的键

        // 将 JSON 字符串添加到 Redis 列表中
        redisTemplate.opsForList().rightPush(redisKey, searchLogDTO.getKeyword());

        // 设置键的过期时间，例如 1 天
//        redisTemplate.expire(redisKey, 1, TimeUnit.DAYS);

        // 修剪列表，使其只包含最后 10 条记录
        redisTemplate.opsForList().trim(redisKey, -10, -1);

        // 调用服务进行搜索
        return songService.searchSong(searchLogDTO);
    }



    /**
     *  搜索歌手
     * @param keyword
     * @return
     */
    @GetMapping("/searchSinger/{keyword}")
    public List<Singer> searchSinger(@PathVariable("keyword") String keyword) {
        return songService.searchSinger(keyword);
    }
    /**
     *  搜索专辑
     * @param keyword
     * @return
     */
    @GetMapping("/searchAlbum/{keyword}")
    public List<Album> searchAlbum(@PathVariable("keyword") String keyword) {
        return songService.searchAlbum(keyword);
    }


    @GetMapping("/getMusicType")
    public List<String> getMusicType() {
        return songService.getMusicType();
    }

    @PostMapping("/addLikeType")
    public List<Song> addLikeType(@RequestBody LikeType likeType)
    {
        System.out.println("接收的："+likeType);
        return songService.addLikeType(likeType);
    }

    @GetMapping("/getLikeTypeMusic/{userId}")
    public List<Song> getLikeTypeMusic(@PathVariable("userId") int userId) {
        return songService.getLikeTypeMusic(userId);
    }

    @PostMapping("/getWaitingSongList")
    public List<Song> getWaitingSongList(@RequestBody int [] songIds) {
        System.out.println("接收的1111："+songIds);
//        System.out.println("接收"+searchLogDTO);
        return songService.getWaitingSongList(songIds);
    }

    /**
     * 获取离线推荐列表中的歌曲
     * @param userId
     * @throws InterruptedException
     */
    @GetMapping("/getOffLineRecommendSongs/{userId}")
    public List<Song> getOffLineRecommendSongs(@PathVariable("userId") int userId) {
        return songService.getOffLineRecommendSongs(userId);
    }

    /**
     * 实时推荐算法
     * @param event
     * @throws InterruptedException
     */
    @PostMapping("/getOnLineRecommendSongs")
    public List<Song> getOnLineRecommendSongs(@RequestBody List<UserActionEventVo> event) throws InterruptedException {

        System.out.println("实时接收的："+event);
        List<UserActionEvent> userActionEvents = new ArrayList<>();
        for (UserActionEventVo userActionEvent : event) {
            UserActionEvent userActionEvent1 = new UserActionEvent();

            // 设置 userId
            if (userActionEvent.getUserId() != null) {
                userActionEvent1.setUserId(userActionEvent.getUserId().toString());
            } else {
                userActionEvent1.setUserId(null);
            }

            // 设置 songId，并避免 NullPointerException
            Long songId = userActionEvent.getSongId();
            if (songId != null) {
                userActionEvent1.setSongId(songId.toString());
            } else {
                userActionEvent1.setSongId(null);
            }

            // 设置 action 类型
            String action = userActionEvent.getAction();
            if ("play".equals(action)) {
                userActionEvent1.setAction(ActionType.PLAY);
            } else if ("favorite".equals(action)) {
                userActionEvent1.setAction(ActionType.FAVORITE);
            } else if ("search".equals(action)) {
                userActionEvent1.setAction(ActionType.SEARCH);
            } else {
                // 如果 action 不匹配已知类型，可以设置为默认值或抛出异常
                userActionEvent1.setAction(null); // 或者根据业务需求处理
            }
            //设置keyword
            if(userActionEvent.getKeyword()!=null){
                userActionEvent1.setKeyword(userActionEvent.getKeyword());
            }else {
                userActionEvent1.setKeyword(null);
            }

            // 将转换后的对象添加到列表中
            userActionEvents.add(userActionEvent1);
        }
        // 将List<T>转化为BlockingQueue<T>类型数据
        BlockingQueue<UserActionEvent> queue1 = new LinkedBlockingQueue<>(userActionEvents);
        return songService.getOnLineRecommendSongs(queue1);
    }

}
